//
// Created by hjie on 23-10-6.
//

#include "date_filter.h"
#include "base_util.h"
#include <cstdio>
#include <strings.h>


DateFilter::DateFilter()
{
	m_input_filter_ctx = nullptr;
	m_output_filter_ctx = nullptr;
	m_filter_graph = nullptr;
	m_is_init_success = false;
}

DateFilter::~DateFilter()
{
	if (m_filter_graph)
	{
		avfilter_graph_free(&m_filter_graph);
	}
	m_is_init_success = false;
}

void DateFilter::CodeConfig(CodecConfig &codec_config)
{
	m_is_set_config = true;
	m_input_parameter = codec_config;
}

bool DateFilter::InitDateFilter(DateDrawTextConfig & config)
{

	if (!m_is_set_config)
	{
		PrintLogMsg("no config input parameter");
		return false;
	}
	m_is_init_success = false;
	AVFilterInOut * input_link = avfilter_inout_alloc();
	if (!input_link)
	{
		return false;
	}

	m_scope_guard.AddFilterInOut(input_link);

	AVFilterInOut * output_link = avfilter_inout_alloc();
	if (!output_link)
	{
		return false;
	}
	m_scope_guard.AddFilterInOut(output_link);

	const AVFilter * buffer_filter = avfilter_get_by_name("buffer");
	if (!buffer_filter)
	{
		return false;
	}
	const AVFilter * buffersinker_filter = avfilter_get_by_name("buffersink");
	if (!buffersinker_filter)
	{
		return false;
	}
	char args[1024] = {0};
	AVRational time_base = m_input_parameter.Timebase();
	snprintf(args, sizeof(args), "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:frame_rate=24/1", 
		m_input_parameter.Width(),m_input_parameter.Height(),m_input_parameter.PixFmt(),time_base.num, time_base.den);

	printf("%s.\n",args);

	m_filter_graph = avfilter_graph_alloc();
	if (!m_filter_graph)
	{
		return false;
	}
	int result = avfilter_graph_create_filter(&m_input_filter_ctx, buffer_filter, "in", args, nullptr, m_filter_graph);
	if (result < 0)
	{
		PrintLog(result);
		return false;
	}
	result = avfilter_graph_create_filter(&m_output_filter_ctx, buffersinker_filter, "out", nullptr, nullptr, m_filter_graph);
	if (result < 0)
	{
		PrintLog(result);
		return false;
	}
	enum AVPixelFormat pix_fmts[] = {AV_PIX_FMT_NV12, AV_PIX_FMT_NONE};
	av_opt_set_int_list(m_output_filter_ctx, "pix_fmts", pix_fmts, AV_PIX_FMT_NONE, AV_OPT_SEARCH_CHILDREN);

	bzero(args, sizeof(args));
	int length = snprintf(args, sizeof(args), "drawtext=text='%{localtime}'");
	if (config.m_font_size)
	{
		length += snprintf(args + length, sizeof(args) - length, ":fontsize=%d", config.m_font_size);
	}
	if (!config.m_font_color.empty())
	{
		length += snprintf(args + length, sizeof(args) - length, ":fontcolor=%s", config.m_font_color.c_str());
	}
	if (config.m_box > 0)
	{
		length += snprintf(args + length, sizeof(args) - length, ":box=%d", config.m_box);
	}
	if (!config.m_box_color.empty())
	{
		length += snprintf(args + length, sizeof(args) - length, ":boxcolor=%s", config.m_box_color.c_str());
	}

	if (config.m_x_position > 0)
	{
		length += snprintf(args + length, sizeof(args) - length, ":x=%d", config.m_x_position);
	}
	if (config.m_y_position > 0)
	{
		length += snprintf(args + length, sizeof(args) - length, ":y=%d", config.m_y_position);
	}

	std::string content = args;

	PrintLogMsg(content);

	input_link->name    = av_strdup("out");
	input_link->pad_idx = 0;
	input_link->filter_ctx = m_output_filter_ctx;
	input_link->next    = nullptr;

	output_link->name    = av_strdup("in");
	output_link->pad_idx = 0;
	output_link->filter_ctx = m_input_filter_ctx;
	output_link->next    = nullptr;

	PrintLogMsg(content);

	result = avfilter_graph_parse_ptr(m_filter_graph, content.c_str(), &input_link, &output_link, nullptr);
	if (result < 0)
	{
		PrintLog(result);
		return false;
	}
	m_scope_guard.ClearInOut();
	m_scope_guard.ClearFilterCtx();
	// check parameter
	result = avfilter_graph_config(m_filter_graph, nullptr);
	if (result < 0)
	{
		PrintLog(result);
		return false;
	}
	m_is_init_success = true;
	return true;
}

bool DateFilter::InitDateFilter(int font_size, const std::string &font_color, int x_pos, int y_pos, int box, const std::string box_color)
{
	return false;
}
